#ifndef TYPEDEF
#define TYPEDEF

#include <map>
#include <array>
#include <tuple>
#include <thread>
#include <cstring>
#include <cstdint>
#include <shared_mutex>
#include <condition_variable>

// 枚举值定义
enum REGVAL
{
	Code,
	Cause,
	Status,
	IE,
	IT,
	IDTR,
	PDTR = 7,
	RetAddr = 11,
	Stack = 14
};
enum FLAG
{
	Zero = 1,
	Pos = 2,
	Neg = 4,
	IntEN = 1 << 8,
	IntTR = 1 << 9,
	Priv = 1 << 10,
	Error = 1 << 16,
	Halt = 1 << 17,
	CacheEN = 1 << 18,
	TLB_EN = 1 << 19,
	PageEN = 1 << 20,
	Block = 1 << 24,
	Master = 1 << 25,
	Slave = 1 << 26
};
enum ACCESS
{
	R = 1,	// 读
	W = 2,	// 写
	X = 4,	// 执行
	P = 8,	// 特权值
	IO = 16 // IO操作
};
enum PIOTYPE : uint8_t
{
	NONE,
	SEIN = 1,
	SEOUT = 2,
	BLIN = 4,
	BLOUT = 8,
	BLIO = 12,
	TIMER = 16,
	MEMIN = 32,
	MEMOUT = 64
};
enum PIOSTATUS : uint16_t
{
	DONE = 0,
	READY = 1,
	READ = 2,
	WRITE = 4,
	BUSY = 8,
	SET0 = 0x40,
	SET1 = 0x50,
	SET2 = 0x60,
	GET0 = 0x80,
	GET1 = 0x90,
	GET2 = 0xa0,
	BAD = 0x1000
};
#define INPUT 1
#define OUTPUT 2
#define DATA 4
#define CONTROL 8
#define SHUTDOWN 128

using CoreBus = std::tuple<uint8_t, uint8_t, uint64_t>; // CoreID,RegTarget,RegValue
class Mutex
{
private:
	std::mutex mtx;
	std::condition_variable cv;
	bool locker;

public:
	Mutex() : locker(1) {}
	void lock()
	{
		std::unique_lock<std::mutex> lock(mtx);
		cv.wait(lock, [this]
				{ return !locker; });
		locker = true;
	}
	void unlock()
	{
		std::lock_guard<std::mutex> lock(mtx);
		locker = false;
		cv.notify_all(); // 唤醒所有等待线程
	}
	bool try_lock()
	{
		return !locker;
	}
};

template <typename T>
class Semaphore
{
private:
	std::shared_mutex mtx;
	T value;

public:
	Semaphore() = default;
	Semaphore &operator=(const Semaphore &other)
	{
		this->value = other.value;
		return *this;
	}
	void rlock() { mtx.lock_shared(); }
	void r_unlock() { mtx.unlock_shared(); }
	void w_lock() { mtx.lock(); }
	void w_unlock() { mtx.unlock(); }
	inline T &get() { return value; }
};

struct MessageBus // 提供片上消息通讯
{
	uint64_t sregs[8][2];
	Mutex cMAR, cMDR, tMAR, dMAR, dMDR, needLoad, done;
	uint64_t MAR, MDR;
	uint16_t size;
	uint16_t access;
	bool priv, fresh;
};
struct IOMessage
{
	uint64_t addr;								 // 地址
	Mutex start, end;							 // 用于同步IO操作
	Semaphore<std::pair<uint16_t, uint16_t>> id; // 确定执行读写的处理器，用于传递中断
	uint16_t port;								 // 端口号，用于IO通道选择
	uint8_t label;								 // 记录IO操作类型
	bool intEN;									 // true表示中断触发
};

#endif